<template>
  <el-upload
    class="upload-file"
    :action="action"
    :on-preview="handleFilePreview"
    :on-remove="handleFileRemove"
    :before-remove="handleFilebeforeRemove"
    :limit="limit"
    :auto-upload="true"
    :on-exceed="handleFileExceed"
    :file-list="fileList"
    :before-upload="handleFileBeforeUpload"
    :on-success="handleFileUploadSuccess"
    :accept="acceptType"
    :multiple="multiple"
    :headers="headers"
    :http-request="handleMultipleFileUpload"
    :name="name"
  >
    <el-button size="small" type="primary">{{ $t('jspFileUpload.upload') }}</el-button>
    <div slot="tip" class="el-upload__tip">{{ uploadDefaultTip }}</div>
  </el-upload>
</template>

<script>
import request from '@/utils/request'
export default {
  name: 'JspFileUpload',
  components: {},
  props: {
    // 默认列表
    defaultList: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 上传地址
    action: {
      type: String,
      default: ''
    },
    // 上传类型：不填写默认所有
    // 格式：.doc,.xls,.zip,.rar等
    accept: {
      type: String,
      default: ''
    },
    // 上传数量限制
    limit: {
      type: Number,
      default: 1
    },
    // 上传数量限制，默认2M
    size: {
      type: Number,
      default: 2
    },
    // 批量上传支持
    multiple: {
      type: Boolean,
      default: true
    },
    // 上传要求提示信息
    uploadTip: {
      type: String,
      default: ''
    },
    // 请求头设置
    headers: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 上传字段名称
    name: {
      type: String,
      default: 'file'
    }
  },
  data() {
    const uploadDefaultTip = this.$t('jspFileUpload.upload_tips', { type: this.accept, limit: this.limit, size: this.size })
    return {
      fileList: this.defaultList,
      acceptType: this.accept,
      uploadDefaultTip: this.uploadTip || uploadDefaultTip
    }
  },
  watch: {
    defaultList(newVal) {
      if (this.defaultList.length > 0 && this.fileList.length === 0) {
        this.fileList = this.defaultList = newVal
      }
    }
  },
  methods: {
    // 移除已上传文件
    handleFileRemove(file) {
      if (file && file.status === 'success') {
        this.fileList = this.fileList.filter((currentValue) => {
          return currentValue.uid !== file.uid
        })
        this.change()
        this.$emit('remove', file, this.fileList)
      }
    },
    // 文件预览/下载文件
    handleFilePreview(file) {
      this.$emit('preview', file)
    },
    // 上传数量限制
    handleFileExceed(files, fileList) {
      this.$message.warning(this.$t('jspFileUpload.on_exceed_tips', { limit: this.limit }))
    },
    // 文件移除前判断
    handleFilebeforeRemove(file, fileList) {
      //   return this.$confirm(`确定移除 ${file.name}？`)
    },
    // 上传前事件
    handleFileBeforeUpload(file) {
      let isFileType = true
      const ext = file.name.substring(file.name.lastIndexOf('.')).toLowerCase()
      if (this.accept !== '') {
        isFileType = this.acceptType.split(',').some((e) => {
          return e.replace(/\s+/g, '').toLowerCase() === ext
        })
        if (!isFileType) {
          this.cancelSelectedNotify(this.$t('jspFileUpload.acceptType_tips', { acceptType: this.accept }), file)
        }
      }
      const isSize = file.size / 1024 / 1024 < this.size
      if (!isSize) {
        this.cancelSelectedNotify(this.$t('jspFileUpload.size_tips', { size: this.size }), file)
      }
      return isFileType && isSize
    },
    // 【作废】单文件上传成功
    handleFileUploadSuccess(response, file, fileList) {
      if (this.multiple) return false
      if (response.status) {
        response.data.items.forEach((i, index) => {
          this.fileList.push({ id: i.id ?? '', name: i.name ?? '', path: i.path ?? '', url: i.url ?? '' })
        })
        this.change()
      } else {
        this.$emit('error', response.message)
      }
    },
    // 自定义多上传
    async handleMultipleFileUpload(params) {
      const validate = this.handleFileBeforeUpload(params.file)
      if (validate) {
        const formData = new FormData()
        formData.append(this.name, params.file, params.file.name)
        let error_upload = false
        await request.post(this.action, formData).then((response) => {
          if (response.status) {
            response.data.items.forEach((i, index) => {
              this.fileList.push({ id: i.id ?? '', name: i.name ?? '', path: i.path ?? '', url: i.url ?? '' })
            })
            this.change()
          } else {
            error_upload = true
          }
        }).catch(() => {
          error_upload = true
        })

        // 移除文件
        if (error_upload) {
          this.fileList = this.fileList.filter((currentValue) => {
            return currentValue.uid !== params.file.uid
          })
          this.$emit('remove', params.file, this.fileList)
          error_upload = false
        }
      }
    },
    // 最终返回的处理结果：
    // 触发：上传成功、删除文件时
    change() {
      const ids = this.fileList.map((currentValue) => currentValue.id).join(',')
      const result = { ids, fileList: this.fileList }
      this.$emit('change', result)
    },
    // 文件选择错误提示
    cancelSelectedNotify(message, file) {
      var h = this.$createElement
      setTimeout(() => {
        this.$notify.error({
          title: this.$t('jspFileUpload.canceled_select'),
          message: h('i', {}, [
            h('p', file ? file.name : ''),
            h('p', message)
          ])
        })
      }, 100)
    }
  }
}
</script>

<style>
</style>
